package org.jeecg.modules.hc.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.util.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.hc.entity.HcAliPay;
import org.jeecg.modules.hc.entity.HcOrder;
import org.jeecg.modules.hc.enums.HcPaymentMethodEnum;
import org.jeecg.modules.hc.mapper.HcAliPayMapper;
import org.jeecg.modules.hc.service.IHcAliPayService;
import org.jeecg.modules.hc.service.IHcOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

/**
 * @Description: 支付宝支付
 * @Author: jeecg-boot
 * @Date: 2023-01-12
 * @Version: V1.0
 */
@Slf4j
@Service
public class HcAliPayServiceImpl extends ServiceImpl<HcAliPayMapper, HcAliPay> implements IHcAliPayService {

    private final String privateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDM5UmfMBFScnOCltaRbXeALSJ1iOomb3baHeXbrElqvOn76ZvjrHma/+ULXDVmKkK+V7rygPcjEKZdawycgtUb8CMUACvpaQrmn3JrIRcrD8GpivPPI23bSRacisXgidyiKU4WkXc8bJg34bZX1gi2ateTFGu1txDX8R3mc+NEPZvdN8NBei0BMEZrP5WjOWsBvlazCGAKzbNdGtsVxND+fjd4/czBBuAXAFwVSJCG3QFvQoYxj7jq30F4Frve8hiu+TzERvba6e096Wg5ea+Y8TMLnMgM5/0wXHHPmfVMUBx2v9qOx4Sj4LP2gC/EBSgHfUoj2OJ/dBCOOHWXcpcdAgMBAAECggEBAMX24uMDNjlKi4Ao7Lcl5Mfa0+hrmI/6MgMbz/Imy+htDkVuuEeJZRT1GP+Y358ORd5SNTYIlL80XwjzXQP7BJwxsDKq18J00ytv8sS++/uHBb4hmt8PhBzSyR4GlpkTmjCzZ9c2RNYEti2Hzv2etlxJbm+U01yGu6doN1NptLNAd5BEJ4F7J05CWOiDBTlNBzZSEnrALbDL3VXQFH48byhSD9NcJCg4sHuZWJ1/j5HCy60mIb7QlyNl1CaAVQjsKvFrytHy36CQ5lboQAiMFT7JyRJLYBIZHuta+RzGnjkdXpmSUN+6d6u1SVf6P9R8a3F7TbPV2DX3M23WUgWMZaECgYEA9mNPOAZp1kv/jrGIzFY1kKRetUGOhLJU0VaUMZDRK/1/6rE0hf93LXZ5jF0Yj6ztEemL2DQnFxMJ20HK3C2LnAa9hYaPvsczCbXhycpNXCTTnR1T+IwJQ5n17708W2DLnnKDDfUwvqs7LYviqySLpo15u9+Ko1Adxy54Jm9tmSsCgYEA1OOXpz/4JHjtafWyEsSlJhFUFKoIyBjg18xRYgOroDKizJSih9iilWdFXPgIfcHU6B2oISVHbG13s5fLW7GGXLYdIkZ9erDnBUQ+QGh2HFxYzrWyiEr7DcrSY3F9STD6KNwo9nHCqoTWFbW8Ljz4lZIM3750Ckmig9S7KslS3NcCgYEA5komNiBQdhrsjyvCx/Jf+ISZfOL8WWzxOASrWLSZvXsgP3VHuWLwuo58x0QQe+HOZ6qZqgf87WU/Fi8lc6wiTEBEjfQakN9RBed5VYl/yvskyzopTSteUVAq/dwq+OG9D6jKc5ZT7DLRih2wS/RJju+283HZ/BEa9Bur84i8sKcCgYBfNO10mbIitYYPlhauOA1XifZdS3Gj8yRSvghDWjrd6OdPsMVDFYoYYNfvbOl3PEE4EVNIh4B6qDYZNjB28FyTh8pdssKZJRYcD9n7OfxgUJhS0YVnWIkQMP2IBZAvNF0b+uHC3TtewQtxKBZhY1kUov1o7qa8lxO7+149E04gfwKBgGSODX0eG2qabXdo5Ya4ksZjqz2ReWubPoN0oME9OrvHrOgXwOmR019t9SK43SL0qLcOnPeJKp/GQDoy/SkW87kH2XFtGWdn4aq30D/0/embS5RdxfpSrLv6ehlb8DZ0RlJIJedTXsCTFgf2+6jmP5voRmo/kNSetAl+iHlC8zit";
    private final String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzOVJnzARUnJzgpbWkW13gC0idYjqJm922h3l26xJarzp++mb46x5mv/lC1w1ZipCvle68oD3IxCmXWsMnILVG/AjFAAr6WkK5p9yayEXKw/BqYrzzyNt20kWnIrF4IncoilOFpF3PGyYN+G2V9YItmrXkxRrtbcQ1/Ed5nPjRD2b3TfDQXotATBGaz+VozlrAb5WswhgCs2zXRrbFcTQ/n43eP3MwQbgFwBcFUiQht0Bb0KGMY+46t9BeBa73vIYrvk8xEb22untPeloOXmvmPEzC5zIDOf9MFxxz5n1TFAcdr/ajseEo+Cz9oAvxAUoB31KI9jif3QQjjh1l3KXHQIDAQAB";
    private final String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmbJVDHeWdXPVJHSvna9CG4i2xWK/qbEtb9LB8NXSPw1lKlizJRJMMZWrrIoOXNQnVpzmh9QOlEkYjBGQtyhzFlAB1Myn0wy6F3ONQisNho4M7ahhpwFrJ913Zr3ir+eK9Jd1Cg1uruaejQzOTbvTGNIXdSDSHEHSrq72UjBP2kWYXIaiwVXTCMirfg+cxSA3/SJ6TdkG0k9Oc1aLLo3PUfk49ebQuWxKdRqAOr2pZkBpzFxBfkTnk6pcfE30qg+ReusaEIVbdzIUODkDHPQDeSoQmZlB1xa4240nxwGwtzN7//k4Ag3Bz5meHDMDksKlmpwTSUCz9sWTAdKJWYQEbQIDAQAB";
    private final String appId = "2021003163678411";
    private final String appIdNew = "2021004126684141";

    @Lazy
    @Autowired
    private IHcOrderService hcOrderService;

    public boolean paynotify(Map<String, String> receiveMap) throws Exception {
        boolean signVerified = AlipaySignature.rsaCheckV1(receiveMap, alipayPublicKey, "UTF-8", "RSA2");

        if (signVerified) {
            String tradeStatus = receiveMap.get("trade_status");
            if ("TRADE_FINISHED".equals(tradeStatus) || "TRADE_SUCCESS".equals(tradeStatus)) {
                String out_trade_no = receiveMap.get("out_trade_no");
                HcAliPay hcAliPay = this.getOne(new LambdaQueryWrapper<HcAliPay>()
                        .eq(HcAliPay::getOutTradeNo, out_trade_no)
                );
                String gmt_payment = receiveMap.get("gmt_payment");

                if (StringUtils.isNotBlank(gmt_payment)) {
                    hcAliPay.setSuccessTime(DateUtils.parseDate(gmt_payment, "yyyy-MM-dd HH:mm:ss"));
                    this.updateById(hcAliPay);
                }

                HcOrder hcOrder = hcOrderService.getOne(new LambdaQueryWrapper<HcOrder>()
                        .eq(HcOrder::getPaymentId, hcAliPay.getId())
                        .in(HcOrder::getPaymentMethod, HcPaymentMethodEnum.ALIPAY, HcPaymentMethodEnum.WALLET_ALIPAY)
                );

                //获取下单时保存的订单信息
                HcOrder order = JSON.parseObject(hcOrder.getObjectJson(), HcOrder.class);
                order.setId(hcOrder.getId());
                order.setHcAliPay(hcAliPay);
                hcOrderService.createOrder(order);
            }
        }

        return signVerified;
    }

    public HcAliPay pay(String userId, BigDecimal total) throws AlipayApiException {
        String outTradeNo = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + RandomUtils.getRandomStr();
        String subject = "用膳团";

        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
        alipayConfig.setAppId(appId);
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setAlipayPublicKey(alipayPublicKey);
        alipayConfig.setFormat("json");
        alipayConfig.setCharset("UTF8");
        alipayConfig.setSignType("RSA2");
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(outTradeNo);
        model.setTotalAmount(total.toString());
        model.setSubject(subject);
        model.setProductCode("QUICK_WAP_WAY");
        request.setBizModel(model);
        request.setNotifyUrl("https://admin.yongshantuan.cn/jeecg-boot/hc/hcAliPay/notify");

        HcAliPay aliPay = new HcAliPay().setUserId(userId).setSubject(subject).setOutTradeNo(outTradeNo)
                .setTotalAmount(total);

        AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
        log.info(response.getBody());

        if (response.isSuccess()) {
            aliPay.setBody(response.getBody()).setTradeNo(response.getTradeNo());
        } else {
            log.error(response.getMsg());
            throw new JeecgBootException("调用失败");
        }

        this.save(aliPay);
        return aliPay;
    }

    public HcAliPay preNativePay(String userId,BigDecimal total) throws AlipayApiException {
        String outTradeNo = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + RandomUtils.getRandomStr();
        String subject = "用膳团";

        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                appId,privateKey,"json","GBK",alipayPublicKey,"RSA2");
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        JSONObject model = new JSONObject();
        model.put("out_trade_no", outTradeNo);
        model.put("total_amount", total);
        model.put("subject", subject);
//        request.setNotifyUrl("https://admin.yongshantuan.cn/jeecg-boot/hc/hcAliPay/notify");

        //// 商品明细信息，按需传入
        // JSONArray goodsDetail = new JSONArray();
        //JSONObject goods1 = new JSONObject();
        //goods1.put("goods_id", "goodsNo1");
        //goods1.put("goods_name", "子商品1");
        //goods1.put("quantity", 1);
        //goods1.put("price", 0.01);
        //goodsDetail.add(goods1);
        //bizContent.put("goods_detail", goodsDetail);
        //// 扩展信息，按需传入
        //JSONObject extendParams = new JSONObject();
        //extendParams.put("sys_service_provider_id", "2088511833207846");
        //bizContent.put("extend_params", extendParams);

        //// 结算信息，按需传入
        //JSONObject settleInfo = new JSONObject();
        //JSONArray settleDetailInfos = new JSONArray();
        //JSONObject settleDetail = new JSONObject();
        //settleDetail.put("trans_in_type", "defaultSettle");
        //settleDetail.put("amount", 0.01);
        //settleDetailInfos.add(settleDetail);
        //settleInfo.put("settle_detail_infos", settleDetailInfos);
        //bizContent.put("settle_info", settleInfo);

        //// 二级商户信息，按需传入
        //JSONObject subMerchant = new JSONObject();
        //subMerchant.put("merchant_id", "2088000603999128");
        //bizContent.put("sub_merchant", subMerchant);

        //// 业务参数信息，按需传入
        //JSONObject businessParams = new JSONObject();
        //businessParams.put("busi_params_key", "busiParamsValue");
        //bizContent.put("business_params", businessParams);

        //// 营销信息，按需传入
        //JSONObject promoParams = new JSONObject();
        //promoParams.put("promo_params_key", "promoParamsValue");
        //bizContent.put("promo_params", promoParams);

        request.setBizContent(model.toString());

        AlipayTradePrecreateResponse response = alipayClient.execute(request);
        System.out.println(response.getQrCode());
        log.info(response.getBody());


        HcAliPay aliPay = new HcAliPay().setUserId(userId).setSubject(subject).setOutTradeNo(outTradeNo)
                .setTotalAmount(total).setQrCode(response.getQrCode());

        if(response.isSuccess()){
            aliPay.setBody(response.getBody()).setTradeNo(response.getOutTradeNo());
            System.out.println("调用成功");
        } else {
            log.error(response.getMsg());
            throw new JeecgBootException("获取支付宝二维码失败");
        }

        this.save(aliPay);
        return aliPay;
    }

    public HcAliPay queryPay(String payId) throws AlipayApiException {
        HcAliPay aliPay = this.getById(payId);

        if (aliPay == null) {
            throw new JeecgBootException("订单号不存在");
        }

        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", appId, privateKey, "json", "GBK", alipayPublicKey, "RSA2");
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", aliPay.getOutTradeNo());
        request.setBizContent(bizContent.toString());
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        log.info(response.getBody());

        if (response.isSuccess()) {
            System.out.println("调用成功");
            HcAliPay aliPayUpd = new HcAliPay().setId(aliPay.getId())
                    .setBuyerLogonId(response.getBuyerLogonId())
                    .setTradeStatus(response.getTradeStatus())
                    .setUpdateTime(new Date());

            if (response.getSendPayDate() != null) {
                aliPayUpd.setSuccessTime(response.getSendPayDate());
            }

            this.updateById(aliPayUpd);
            aliPayUpd.setTotalAmount(aliPay.getTotalAmount());
            return aliPayUpd;
        } else {
            log.error(response.getMsg());
            return aliPay;
        }
    }

    @Override
    public HcAliPay queryAliPayRes(String outTradeNum) throws AlipayApiException {
        HcAliPay aliPay = this.getOne(new LambdaQueryWrapper<HcAliPay>().eq(HcAliPay::getOutTradeNo,outTradeNum));

        if (aliPay == null) {
            throw new JeecgBootException("订单号不存在");
        }

        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", appId, privateKey, "json", "GBK", alipayPublicKey, "RSA2");
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", aliPay.getOutTradeNo());
        request.setBizContent(bizContent.toString());
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        log.info(response.getBody());

        if (response.isSuccess()) {
            System.out.println("调用成功");

            aliPay.setBuyerLogonId(response.getBuyerLogonId())
                    .setTradeStatus(response.getTradeStatus())
                    .setUpdateTime(new Date());

            if (response.getSendPayDate() != null) {
                aliPay.setSuccessTime(response.getSendPayDate());
            }
            aliPay.setTotalAmount(aliPay.getTotalAmount());
            this.updateById(aliPay);

            HcOrder hcOrder = hcOrderService.getOne(new LambdaQueryWrapper<HcOrder>()
                    .eq(HcOrder::getPaymentId, aliPay.getId())
                    .in(HcOrder::getPaymentMethod, HcPaymentMethodEnum.PC_ZFB)
            );
            //获取下单时保存的订单信息
            HcOrder order = JSON.parseObject(hcOrder.getObjectJson(), HcOrder.class);
            order.setId(hcOrder.getId());
            order.setHcAliPay(aliPay);
            HcOrder order1 = hcOrderService.createOrder(order);
            aliPay.setId(order1.getId());
        }
        return aliPay;
    }
}
